package io.github.uicdb.gravity_generator.block;

import com.google.common.collect.ImmutableSet;
import io.github.uicdb.gravity_generator.GGConfig;
import io.github.uicdb.gravity_generator.GGRegistries;
import io.github.uicdb.gravity_generator.GGUtils;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.EnergyStorage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Objects;

public class BEGravityGenerator extends BlockEntity  {
    private final EnergyStorage energyStorage;
    private static final ImmutableSet<Direction> DIRECTIONS= ImmutableSet.of(Direction.DOWN,Direction.EAST,Direction.WEST,Direction.NORTH,Direction.SOUTH);
    public BEGravityGenerator(BlockPos blockPos, BlockState state) {
        super(GGRegistries.GRAVITY_GENERATOR_TYPE.get(), blockPos, state);
        energyStorage=new EnergyStorage(GGConfig.GG_STORAGE_SIZE.get(),Integer.MAX_VALUE,GGConfig.GG_EXTRACT_SIZE.get());
    }

    public EnergyStorage getEnergyStorage() {
        return energyStorage;
    }

    public void conversionEnergy(Entity entity, float distance){
        if(level instanceof ServerLevel) {
            String entityString= Objects.requireNonNullElse(entity.getType().getRegistryName(),GGUtils.EMPTY).toString();
            boolean isValidEntity=GGConfig.BLACK_LIST_MODE.get()?!GGConfig.BLACK_LIST.get().contains(entityString):GGConfig.WHITE_LIST.get().contains(entityString);
            if(isValidEntity) {
                int add = (int) (distance * GGConfig.GG_CONVERSION_RATE.get());
                getEnergyStorage().receiveEnergy(Math.max(0, add), false);
            }
        }
    }
    @NotNull
    @Override
    public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
        if(cap==CapabilityEnergy.ENERGY&&DIRECTIONS.contains(side))return LazyOptional.of(()->energyStorage).cast();
        return LazyOptional.empty();
    }
    public void tick(){
        GGUtils.transferEnergy(energyStorage,DIRECTIONS,level,getBlockPos());
    }

    @Override
    protected void saveAdditional(@NotNull CompoundTag compoundTag) {
        super.saveAdditional(compoundTag);
        compoundTag.put("energy",energyStorage.serializeNBT());
    }

    @Override
    public void load(@NotNull CompoundTag compoundTag) {
        super.load(compoundTag);
        if(compoundTag.contains("energy")){
            Tag tag=compoundTag.get("energy");
            energyStorage.deserializeNBT(tag);
        }
    }
}
